package com.xiyuan.smartutils;

/**
 * 长整型相关工具类
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */

public final class Longs {
    
    private Longs() {}
    
    public static final int LONG_LEN = 19;
    private static final int MIN_MAX = 9;
    
    /**
     * 字符串转换为int,异常不处理 注:默认10进制
     */
    public static long toLong(String s) {
        return Long.parseLong(s);
    }
    
    /**
     * 字符串转换为int 如果异常则返回异常值
     */
    public static long toLong(String s, long defaultValue) {
        try {return Long.parseLong(s);} catch (NumberFormatException e) {return defaultValue;}
    }
    
    /**
     * 对象转换为int 如果异常则返回异常值
     */
    public static long toLong(Object o, long defaultValue) {
        if (o == null) {return defaultValue;}
        else if (o instanceof Integer) {
            return (Integer) o;
        }
        else if (o instanceof Long) {
            return (Long) o;
        }
        else if (o instanceof String) {
            return toLong((String) o, defaultValue);
        }
        else {return defaultValue;}
    }
    
    
    /**
     * 计算 数值长度
     * <p>
     * 例如：
     * 99 返回 2，
     * 85 返回 2
     * 3699 返回 4，
     * 以此类推
     *
     * @param val 数值
     * @return 数值的长度
     */
    public static int length(long val) {
        if (val == 0) {return 1;}
        
        boolean isNegative = false;
        if (val < 0) {
            //负数变为正数
            val = -val;
            isNegative = true;
        }
        
        int len = 0;
        //对值作10的整除
        for (long i = val; i != 0; i /= 10) {
            len++;
        }
        
        return isNegative ? len + 1 : len;
    }
    
    /**
     * 指定长度获取最大值，最大返回 Long.maxValue
     * 例如：
     * length=2, 返回：99；
     * length=3, 返回：999,；
     * length=4, 返回：9999；
     *
     * @param length 指定长度
     * @return 最大值
     */
    public static long getMax(int length) {
        if (length >= LONG_LEN) {return Long.MAX_VALUE;}
        
        if (length <= 0) {return MIN_MAX;}
        
        String maxString = "999999999999999999".substring(0, length);
        return toLong(maxString);
    }
    
    public static int compareUnsigned(long a, long b) {
        //先去掉符号位比，相等再比符号位
        long cmp = (a >>> 1) - (b >>> 1);
        if (cmp != 0) {return cmp > 0 ? 1 : -1;}
        
        cmp = ((a & 1) - (b & 1));
        return cmp > 0 ? 1 : (cmp < 0 ? -1 : 0);
    }
}
